package com.sxu.system.service.sysuser.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sxu.common.core.constants.HttpConstants;
import com.sxu.common.core.domain.LoginUser;
import com.sxu.common.core.domain.R;
import com.sxu.common.core.domain.vo.LoginUserVO;
import com.sxu.common.core.enums.ResultCode;
import com.sxu.common.core.enums.UserIdentity;
import com.sxu.common.security.exception.ServiceException;
import com.sxu.common.security.service.TokenService;
import com.sxu.system.domain.sysuser.SysUser;
import com.sxu.system.mapper.sysuser.SysUserMapper;
import com.sxu.system.domain.sysuser.dto.SysUserSaveDTO;
import com.sxu.system.service.sysuser.ISysUserService;
import com.sxu.system.utils.BCryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RefreshScope
@Slf4j
public class SysUserServiceImpl implements ISysUserService {


    @Autowired
    private SysUserMapper sysUserMapper;

    @Value("${jwt.secret}")
    private String secret;

    @Autowired
    private TokenService tokenService;


    @Override
    public R<String> login(String userAccount, String password) {
        //通过账号在数据库中查询对应的用户信息
        //selectOne 查询数据对应的唯一信息 参数通过lambda表达式的形式传入
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        //相当于 select password form tb_sys_user where user_account = #{userAccount}
        SysUser sysUser = sysUserMapper.selectOne(queryWrapper
                .select(SysUser::getUserId,SysUser::getPassword).eq(SysUser::getUserAccount,userAccount));
        //R loginResult = new R();

        if(sysUser == null ) {
//            loginResult.setCode(ResultCode.FAILED_USER_NOT_EXISTS.getCode());
//            loginResult.setMsg(ResultCode.FAILED_USER_NOT_EXISTS.getMsg());
//            return loginResult;
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        if(BCryptUtils.matchesPassword(password,sysUser.getPassword())) {
//            loginResult.setCode(ResultCode.SUCCESS.getCode());
//            loginResult.setMsg(ResultCode.SUCCESS.getMsg());
//            return loginResult;
            //登录这段代码 C端仍会使用 所以提出来 减少重复代码
//            Map<String,Object> claims = new HashMap<>();
//            String userKey = UUID.fastUUID().toString();
//            claims.put(JwtConstants.LOGIN_USER_ID,sysUser.getUserId());
//            claims.put(JwtConstants.LOGIN_USER_KEY,userKey);
//            String token = JwtUtils.createToken(claims,secret);
//            //Redis中存储敏感信息 用户身份信息 identity
//            //使用什么数据结构 String
//            //key存储什么？ 保证唯一 + 便于维护  同意前缀 logintoken:userId /
//
//            String key = CacheConstants.LOGIN_TOKEN_KEY + userKey;
//            LoginUser loginUser = new LoginUser();
//            loginUser.setIdentity(UserIdentity.ADMIN.getValue());
//            redisService.setCacheObject(key,loginUser, CacheConstants.EXP, TimeUnit.MINUTES);
            //过期时间怎么记录

            return R.ok(tokenService.createToken(sysUser.getUserId(),secret,UserIdentity.ADMIN.getValue(),sysUser.getNickName(),null));
        }
//        loginResult.setCode(ResultCode.FAILED_LOGIN.getCode());
//        loginResult.setMsg(ResultCode.FAILED_LOGIN.getMsg());
//        return loginResult;
        return R.fail(ResultCode.FAILED_LOGIN);
    }

    @Override
    public int add(SysUserSaveDTO sysUserSaveDTO) {
        //代码优化 ——> 看其他模块是否会产生重复代码 将重复代码提取为独立模块

        //参数校验
        List<SysUser> sysUserList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserAccount,sysUserSaveDTO.getUserAccount()));
        if(CollectionUtil.isEmpty(sysUserList)) { //不为空 返回true
            //用户已经存在
            //自定义的异常   公共的异常类
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }
        //将DTO转为实体
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        sysUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));
        //Mybatis plus提供了自动填充字段的功能
//        sysUser.setCreateBy(Constants.SYSTEM_USER_ID);
//        sysUser.setCreateTime(LocalDateTime.now());
        return sysUserMapper.insert(sysUser);
    }

    @Override
    public boolean logout(String token) {
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        return tokenService.deleteLoginUser(token, secret);
    }

    @Override
    public R<LoginUserVO> info(String token) {
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        LoginUser loginUser = tokenService.getLoginUser(token, secret);
        if (loginUser == null) {
            return R.fail();
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        loginUserVO.setNickName(loginUser.getNickName());
        return R.ok(loginUserVO);
    }

    //不是很高级的处理方式
//    private void checkParams(SysUserSaveDTO sysUserSaveDTO) {
//        String password = sysUserSaveDTO.getPassword();
//        if (password == null) {
//            throw new ServiceException();
//        }
//    }
}
